#include "dd_filetomesh.h"
#include "dd_world.h"
#include <stdio.h>
#include <GL/glew.h>
#include "dd_world.h"
#include "dd_object.h"

/* test world
 */
struct dd_world_test2 {
	struct dd_world parent;

	// contains a rotating object
	struct dd_object o;
	float rotation;
};

// constructor - destructor
void dd_world_test2_create(struct dd_world_test2 *);
void dd_world_test2_clean(struct dd_world_test2 *);

/* update
 * keep rotating
 */
void dd_world_test2_update(struct dd_world *w) {
	struct dd_world_test2 *world = (struct dd_world_test2 *) w;
	world->rotation -= 1;
	if (world->rotation < 0) {
		world->rotation += 360;
	}
}

/* draw
 * move back, rotate the world, then draw the object
 */
void dd_world_test2_draw(struct dd_world *w) {
	struct dd_world_test2 *world = (struct dd_world_test2 *) w;

	// move and and rotate
	glPushMatrix();
	glTranslatef(0, 0, -5);
	glRotatef(world->rotation, 0, 1, 0);

	// draw object
	dd_object_draw(&world->o);

	// cancel world's transformations
	glPopMatrix();
}

// constructor
void dd_world_test2_create(struct dd_world_test2 *w) {
	struct dd_world *parent = (struct dd_world *) w;

	// pass update and draw functions to world
	parent->update = dd_world_test2_update;
	parent->draw = dd_world_test2_draw;

	// create the object from "untitled.ply"
	dd_object_create(&w->o);
	dd_filetomesh(&w->o.p, "untitled.ply", 0, 0, DD_PLY);

	// initialise rotation
	w->rotation = 0;
}

void dd_world_test2_clean(struct dd_world_test2 *w) {
}
/* test world
 */
struct dd_world_test {
	struct dd_world parent;

	// contains a rotating object
	struct dd_object o;
	float rotation;
};

// constructor - destructor
void dd_world_test_create(struct dd_world_test *);
void dd_world_test_clean(struct dd_world_test *);

/* update
 * keep rotating
 */
void dd_world_test_update(struct dd_world *w) {
	struct dd_world_test *world = (struct dd_world_test *) w;
	world->rotation += 0.5;
	if (world->rotation >= 360) {
		world->rotation -= 360;
		dd_world_change(sizeof(struct dd_world_test2), (void (*) (struct dd_world *)) dd_world_test2_create);
	}
}

/* draw
 * move back, rotate the world, then draw the object
 */
void dd_world_test_draw(struct dd_world *w) {
	struct dd_world_test *world = (struct dd_world_test *) w;

	// move and and rotate
	glPushMatrix();
	glTranslatef(0, 0, -5);
	glRotatef(world->rotation, 0, 1, 0);

	// draw object
	dd_object_draw(&world->o);

	// cancel world's transformations
	glPopMatrix();
}

// constructor
void dd_world_test_create(struct dd_world_test *w) {
	struct dd_world *parent = (struct dd_world *) w;

	// pass update and draw functions to world
	parent->update = dd_world_test_update;
	parent->draw = dd_world_test_draw;

	// create the object from "untitled.ply"
	dd_object_create(&w->o);
	dd_filetomesh(&w->o.p, "untitled.ply", 0, 0, DD_PLY);

	// initialise rotation
	w->rotation = 0;
}

void dd_world_test_clean(struct dd_world_test *w) {
}

// mark this as the default world
void dd_world_init() {
	dd_world_change(sizeof(struct dd_world_test), (void (*) (struct dd_world *)) dd_world_test_create);
}
